package session

import (
	"context"

	"myapp/internal/model"
	"myapp/internal/service"

	"github.com/gogf/gf/v2/net/ghttp"
)

type sSession struct{}

const (
	sessionKeyUser         = "SessionKeyUser"    // 用户信息存放在Session中的Key
	sessionKeyLoginReferer = "SessionKeyReferer" // Referer存储，当已存在该session时不会更新。用于用户未登录时引导用户登录，并在登录后跳转到登录前页面。
	sessionKeyNotice       = "SessionKeyNotice"  // 存放在Session中的提示信息，往往使用后则删除
)

func init() {
	service.RegisterSession(New())
}

func New() *sSession {
	return &sSession{}
}

// 设置用户Session.
func (s *sSession) SetUser(ctx context.Context, user *model.SessionUser) error {
	r := ghttp.RequestFromCtx(ctx)
	return r.Session.Set(sessionKeyUser, user)
}

// 获取当前登录的用户信息对象，如果用户未登录返回nil。
func (s *sSession) GetUser(r *ghttp.Request) *model.SessionUser {
	v, _ := r.Session.Get(sessionKeyUser)
	if !v.IsNil() {
		var user *model.SessionUser
		_ = v.Struct(&user)
		return user
	}

	return nil
}
func (s *sSession) GetUserFromCtx(ctx context.Context) *model.SessionUser {
	return s.GetUser(ghttp.RequestFromCtx(ctx))
}

// 删除用户Session。
func (s *sSession) RemoveUser(ctx context.Context) error {
	r := ghttp.RequestFromCtx(ctx)
	return r.Session.Remove(sessionKeyUser)
}

// 设置LoginReferer.
func (s *sSession) SetLoginReferer(ctx context.Context, referer string) error {
	if s.GetLoginReferer(ctx) == "" {
		r := ghttp.RequestFromCtx(ctx)
		return r.Session.Set(sessionKeyLoginReferer, referer)
	}
	return nil
}

// 获取LoginReferer.
func (s *sSession) GetLoginReferer(ctx context.Context) string {
	r := ghttp.RequestFromCtx(ctx)
	st := r.Session.MustGet(sessionKeyLoginReferer).String()
	return st
}

// 删除LoginReferer.
func (s *sSession) RemoveLoginReferer(ctx context.Context) error {
	r := ghttp.RequestFromCtx(ctx)

	return r.Session.Remove(sessionKeyLoginReferer)

}

// 设置Notice
func (s *sSession) SetNotice(ctx context.Context, message *model.SessionNotice) error {
	r := ghttp.RequestFromCtx(ctx)

	return r.Session.Set(sessionKeyNotice, message)

}

// 获取Notice
func (s *sSession) GetNotice(ctx context.Context) (*model.SessionNotice, error) {
	r := ghttp.RequestFromCtx(ctx)
	var message *model.SessionNotice
	v, err := r.Session.Get(sessionKeyNotice)
	if err != nil {
		return nil, err
	}
	if err = v.Scan(&message); err != nil {
		return nil, err
	}
	return message, nil

}

// 删除Notice
func (s *sSession) RemoveNotice(ctx context.Context) error {
	r := ghttp.RequestFromCtx(ctx)
	return r.Session.Remove(sessionKeyNotice)
}
